﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using log4net;
using System.Diagnostics;

namespace PicturePortfolio.Logging
{
    public static class Logger 
    {
        #region constants
        internal const string LOG_ERROR_SOURCE = "PicturePortfolio";
        #endregion

        #region member variables
        private static  ILog _logger;
        #endregion

        #region Setup and Initialize
        //public Logger()
        //{
        //    try
        //    {
        //        _logger = LogManager.GetLogger("");
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}


        static Logger()
        {
            log4net.Config.XmlConfigurator.Configure();
            _logger = LogManager.GetLogger("");
        }
        #endregion


        #region LogError
        public static void LogError(string message)
        {
            try
            {
                if (_logger.IsErrorEnabled)
                {
                    _logger.Error(message);
                }
            }
            catch (Exception ex)
            {
                //LogLogFailure(ex.ToString());
            }
        }

        public static void LogError(string message, object arg1)
        {
            try
            {
                if (_logger.IsErrorEnabled)
                {
                    _logger.ErrorFormat(message, arg1);
                }
            }
            catch (Exception ex)
            {
                //LogLogFailure(ex.ToString());
            }
        }

        public static void LogError(string message, object arg1, object arg2)
        {
            try
            {
                if (_logger.IsErrorEnabled)
                {
                    _logger.ErrorFormat(message, arg1, arg2);
                }
            }
            catch (Exception ex)
            {
                //LogLogFailure(ex.ToString());
            }
        }

        public static void LogError(string message, object arg1, object arg2, object arg3)
        {
            try
            {
                if (_logger.IsErrorEnabled)
                {
                    _logger.ErrorFormat(message, arg1, arg2, arg3);
                }
            }
            catch (Exception ex)
            {
                //LogLogFailure(ex.ToString());
            }
        }

        public static void LogError(string message, object[] args)
        {
            try
            {
                if (_logger.IsErrorEnabled)
                {
                    _logger.ErrorFormat(message, args);
                }
            }
            catch (Exception ex)
            {
                //LogLogFailure(ex.ToString());
            }
        }


        public static void LogError(Exception ex)
        {
            try
            {
                LogError(GetExceptionStringForLogging(ex));
            }
            catch (Exception exc)
            {
                //LogLogFailure(exc.ToString());
            }
        }

        public static void LogError(Exception ex, NameValueCollection error)
        {
            try
            {
                var errorMsg = new StringBuilder();
                foreach (string name in error.Keys)
                {
                    errorMsg.AppendFormat("{0} : {1}\n", name, error[name]);
                }
                errorMsg.Append(GetExceptionStringForLogging(ex));
                LogError(errorMsg.ToString());
            }
            catch (Exception exc)
            {
                //LogLogFailure(exc.ToString());
            }
        }

        public static void LogError(Exception ex, string error)
        {
            try
            {
                LogError("{0}\n{1}", error, GetExceptionStringForLogging(ex));
            }
            catch (Exception exc)
            {
                //LogLogFailure(exc.ToString());
            }
        }
        #endregion


        //#region LogInfo
        //public void LogInfo(string message)
        //{
        //    try
        //    {
        //        if (_logger.IsInfoEnabled)
        //        {
        //            _logger.InfoFormat(message);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}

        //public void LogInfo(string message, object arg1)
        //{
        //    try
        //    {
        //        if (_logger.IsInfoEnabled)
        //        {
        //            _logger.InfoFormat(message, arg1);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}

        //public void LogInfo(string message, object arg1, object arg2)
        //{
        //    try
        //    {
        //        if (_logger.IsInfoEnabled)
        //        {
        //            _logger.InfoFormat(message, arg1, arg2);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}

        //public void LogInfo(string message, object arg1, object arg2, object arg3)
        //{
        //    try
        //    {
        //        if (_logger.IsInfoEnabled)
        //        {
        //            _logger.InfoFormat(message, arg1, arg2, arg3);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}

        //public void LogInfo(string message, object[] args)
        //{
        //    try
        //    {
        //        if (_logger.IsInfoEnabled)
        //        {
        //            _logger.InfoFormat(message, args);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}
        //#endregion

        //#region LogDebug
        //public void LogDebug(string message)
        //{
        //    try
        //    {
        //        if (_logger.IsDebugEnabled)
        //        {
        //            _logger.DebugFormat(message);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}

        //public void LogDebug(string message, object arg1)
        //{
        //    try
        //    {
        //        if (_logger.IsDebugEnabled)
        //        {
        //            _logger.DebugFormat(message, arg1);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}

        //public void LogDebug(string message, object arg1, object arg2)
        //{
        //    try
        //    {
        //        if (_logger.IsDebugEnabled)
        //        {
        //            _logger.DebugFormat(message, arg1, arg2);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}

        //public void LogDebug(string message, object arg1, object arg2, object arg3)
        //{
        //    try
        //    {
        //        if (_logger.IsDebugEnabled)
        //        {
        //            _logger.DebugFormat(message, arg1, arg2, arg3);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}

        //public void LogDebug(string message, object[] args)
        //{
        //    try
        //    {
        //        if (_logger.IsDebugEnabled)
        //        {
        //            _logger.DebugFormat(message, args);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogLogFailure(ex.ToString());
        //    }
        //}
        //#endregion

        //#region Log Log Failure
        //public void LogLogFailure(string message)
        //{
        //    try
        //    {
        //        string logName = "Application";
        //        if (!EventLog.SourceExists(LOG_ERROR_SOURCE))
        //        {
        //            EventLog.CreateEventSource(LOG_ERROR_SOURCE, logName);
        //        }
        //        else
        //        {
        //            logName = EventLog.LogNameFromSourceName(LOG_ERROR_SOURCE, Environment.MachineName);
        //        }
        //        var applicationLog = new EventLog(logName) { Source = LOG_ERROR_SOURCE };
        //        applicationLog.WriteEntry(message, EventLogEntryType.Warning);
        //    }
        //    // ReSharper disable EmptyGeneralCatchClause
        //    catch
        //    // ReSharper restore EmptyGeneralCatchClause
        //    {
        //    }
        //}
        //#endregion


        internal static string GetExceptionStringForLogging(Exception ex)
        {
            try
            {
                if (ex != null)
                {
                    var messageToLog = new StringBuilder();
                    messageToLog.Append(ex.Message);
                    messageToLog.AppendLine();
                    messageToLog.Append("Stack Trace: ");
                    messageToLog.AppendLine();
                    messageToLog.Append(ex.StackTrace);
                    messageToLog.AppendLine();
                    if (ex.InnerException != null) messageToLog.Append(GetExceptionStringForLogging(ex.InnerException));
                    return messageToLog.ToString();
                }
                return string.Empty;
            }
            // ReSharper disable EmptyGeneralCatchClause
            catch
            // ReSharper restore EmptyGeneralCatchClause
            {
                // Ignore
            }
            return string.Empty;
        }
    }
}
